package com.oros.db;

import java.io.Serializable;

import com.vaadin.data.Item;

public class AELikeFilter implements AEExtendedFilter, Serializable {


	private static final long serialVersionUID = -6128115246934438387L;
	int colAmount;
	AETableContainer parent;
	final public static int KIND_MIDDLE=0;
	final public static int KIND_LEFT=1;
	final public static int KIND_RIGHT=2;
	final public static int KIND_EXACT=3;
	final public static int CASE_SENSITIVE=4;
	int[] kind,colNo;
	String[] column,vals,origs;
	public AELikeFilter(String[] columns,int[] kinds,String[] values)
	{
		colAmount = columns==null?0:columns.length;
	    int kindAmount = kinds==null?0:kinds.length;
	    kind = new int[colAmount];
	    for(int i=0;i<colAmount;i++)
	    {
	    	kind[i]=i<kindAmount?kinds[i]:KIND_MIDDLE;
	    }
	    column = columns==null?new String[0]:columns;
	    colNo = new int[colAmount];
	    vals = new String[colAmount];
	    origs = new String[colAmount];
	    int valAmount=values==null?0:values.length;
	    for(int i=0;i<colAmount;i++)
	    {
	    	String s=i<valAmount?values[i]:null;
	    	origs[i]=s;
	    	if (s!=null)
	    	{
	    		s = s.trim();
	    		if (s.length()==0) s=null;
	    		else
	    		{
	    			if ((kind[i] & CASE_SENSITIVE)==0) s=s.toLowerCase();
	    		}
	    	}
	    	vals[i]=s;
	    }
	}
	private void fireChange()
	{
		if (parent!=null) parent.refilter_resorter();
	}
	private boolean updateFilterInternal(String[] values)
	{
        int valAmount=values==null?0:values.length;
        boolean anyChange = false;
        for(int i=0;i<colAmount;i++)
        {
             String s=i<valAmount?values[i]:null;
             origs[i]=s;
             if (s!=null)
             {
            	 s=s.trim();
     			if (s.length()==0) s=null;
    			else
    			{
    				if ((kind[i] & CASE_SENSITIVE)==0) s=s.toLowerCase();
    			}
             }
             if (s==vals[i]) continue;
             if (s==null || vals[i]==null || !s.equals(vals[i]))
             {
            	 vals[i]=s;
            	 anyChange=true;
             }
        }
        return anyChange;
	}
	public void updateFilter(String[] values)
	{
		if (updateFilterInternal(values)) fireChange();
	}
	public void updateFilter(int columnNo,String value)
	{
		if (columnNo<0 || columnNo>=colAmount) return;
		origs[columnNo]=value;
		if (value!=null)
		{
			value=value.trim();
			if (value.length()==0) value=null;
			else
			{
				if ((kind[columnNo] & CASE_SENSITIVE)==0) value=value.toLowerCase();
			}
		}
		if (vals[columnNo]==value) return;
		if (vals[columnNo]==null || value==null || !value.equals(vals[columnNo]))
		{
			vals[columnNo]=value;
			fireChange();
		}
	}
	public void updateFilterByType(int columnNo,int type)
	{
		if (columnNo>=0 && columnNo<colAmount && type!=kind[columnNo])
		{
	          kind[columnNo]=type;
	          updateFilterInternal(origs);
	          fireChange();
		}
	}
	@Override
	public boolean passesFilter(Object itemId, Item item)
			throws UnsupportedOperationException {
		AERawItem cp = (AERawItem)item;
		for(int i=0;i<colAmount;i++)
		{
			String vl=vals[i];
			if (vl==null) continue;
			Object o=cp.getColumnValue(colNo[i]);
			if (o==null) return false;
			String s=o.toString().trim();
			int cpKind = kind[i];
			if ((cpKind & CASE_SENSITIVE)==0) s=s.toLowerCase();
			switch(cpKind & 3)
			{
			case KIND_MIDDLE:
				if (s.indexOf(vl)<0) return false;
				break;
			case KIND_LEFT:
				if (!s.startsWith(vl)) return false;
				break;
			case KIND_RIGHT:
				if (!s.endsWith(vl)) return false;
				break;
			case KIND_EXACT:
				if (!s.equals(vl)) return false;
				break;
			}
		}
		return true;
	}

	@Override
	public boolean appliesToProperty(Object propertyId) {
		return true;
	}

	@Override
	public void onCloseEvent() {
		parent=null;
	}

	@Override
	public void setParentContainer(AETableContainer container) {
       parent = container;
       for(int i=0;i<colAmount;i++)
       {
    	   int n=container.getColumnIndex(column[i]);
    	   if (n<0) throw new RuntimeException("Invalid column name in filter: "+column[i]);
    	   colNo[i]=n;
       }
	}

}
